#!/bin/bash
# pg_dump 备份打包脚本，用于数据库迁移

# 脚本目录路径
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
COMMON_DIR="${SCRIPT_DIR}/../common"

# 加载公共工具函数
source "${COMMON_DIR}/utils.sh"

# 初始化环境
LOG_FILE_PREFIX="pg_dump_package"
init
start_timer

# 显示使用说明
show_usage() {
    echo "用法: $0 [选项]"
    echo "选项:"
    echo "  --db=DB_NAME        要打包的数据库名称，默认为 ${POSTGRES_DB}"
    echo "  --backup=BACKUP     要打包的备份文件/目录名称，默认为最新备份"
    echo "  --output=DIR        输出目录，默认为当前目录"
    echo "  --help              显示此帮助信息"
    echo
    echo "示例:"
    echo "  $0 --db=tbscada1                       # 打包最新的 tbscada1 数据库备份"
    echo "  $0 --db=tbscada1 --backup=tbscada1_20230101_120000.dump   # 打包指定备份"
    echo "  $0 --db=tbscada1 --output=/tmp/export  # 指定输出目录"
}

# 解析命令行参数
DB_NAME="${POSTGRES_DB}"
BACKUP="latest"
OUTPUT_DIR="$(pwd)"

for i in "$@"; do
    case $i in
        --db=*)
            DB_NAME="${i#*=}"
            ;;
        --backup=*)
            BACKUP="${i#*=}"
            ;;
        --output=*)
            OUTPUT_DIR="${i#*=}"
            ;;
        --help)
            show_usage
            exit 0
            ;;
        *)
            log_warning "未知参数: $i，将被忽略"
            ;;
    esac
done

log_info "开始打包数据库 ${DB_NAME} 的备份..."

# 确定要打包的备份文件或目录
if [ "${BACKUP}" = "latest" ]; then
    # 使用最新备份的符号链接
    LATEST_LINK="${PGDUMP_BACKUP_DIR}/${DB_NAME}_latest"
    if [ ! -L "${LATEST_LINK}" ]; then
        log_error "找不到最新备份的符号链接: ${LATEST_LINK}"
        exit 1
    fi

    # 获取符号链接指向的实际备份文件
    BACKUP_PATH=$(readlink -f "${LATEST_LINK}")
    if [ ! -e "${BACKUP_PATH}" ]; then
        log_error "符号链接指向的备份文件不存在: ${BACKUP_PATH}"
        exit 1
    fi

    BACKUP_NAME=$(basename "${BACKUP_PATH}")
    log_info "使用最新备份: ${BACKUP_NAME}"
else
    # 检查指定的备份文件是否存在
    if [[ "${BACKUP}" == *"/"* ]]; then
        # 如果包含路径分隔符，使用完整路径
        BACKUP_PATH="${BACKUP}"
    else
        # 否则，在备份目录中查找
        BACKUP_PATH="${PGDUMP_BACKUP_DIR}/${BACKUP}"
    fi

    if [ ! -e "${BACKUP_PATH}" ]; then
        log_error "指定的备份不存在: ${BACKUP_PATH}"
        exit 1
    fi

    BACKUP_NAME=$(basename "${BACKUP_PATH}")
    log_info "使用指定备份: ${BACKUP_NAME}"
fi

# 确保输出目录存在
if [ ! -d "${OUTPUT_DIR}" ]; then
    log_info "创建输出目录: ${OUTPUT_DIR}"
    mkdir -p "${OUTPUT_DIR}"
    if [ $? -ne 0 ]; then
        log_error "无法创建输出目录: ${OUTPUT_DIR}"
        exit 1
    fi
fi

# 创建打包时间戳
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
PACKAGE_NAME="${DB_NAME}_migration_${TIMESTAMP}.tar.gz"
PACKAGE_PATH="${OUTPUT_DIR}/${PACKAGE_NAME}"

# 创建临时目录用于打包
TMP_DIR=$(mktemp -d)
log_info "创建临时目录: ${TMP_DIR}"

# 复制备份文件到临时目录
log_info "复制备份文件到临时目录..."
if [ -d "${BACKUP_PATH}" ]; then
    # 如果是目录格式的备份
    cp -r "${BACKUP_PATH}" "${TMP_DIR}/"
else
    # 如果是文件格式的备份
    cp "${BACKUP_PATH}" "${TMP_DIR}/"
fi

# 创建恢复说明文件
cat > "${TMP_DIR}/README.txt" << EOF
PostgreSQL 数据库 ${DB_NAME} 迁移备份包
创建时间: $(date '+%Y-%m-%d %H:%M:%S')
备份文件: ${BACKUP_NAME}

恢复说明:
1. 解压此包:
   tar -xzf ${PACKAGE_NAME}

2. 使用 pg_restore 恢复数据库:
   # 对于 custom 格式 (.dump)
   pg_restore -h localhost -p 5432 -U postgres -d ${DB_NAME} -v ${BACKUP_NAME}

   # 对于 plain 格式 (.sql)
   psql -h localhost -p 5432 -U postgres -d ${DB_NAME} -f ${BACKUP_NAME}

   # 对于 tar 格式 (.tar)
   pg_restore -h localhost -p 5432 -U postgres -d ${DB_NAME} -v ${BACKUP_NAME}

   # 对于 directory 格式
   pg_restore -h localhost -p 5432 -U postgres -d ${DB_NAME} -v ${BACKUP_NAME}

注意:
- 恢复前，请确保目标服务器已安装 PostgreSQL ${POSTGRES_VERSION}
- 如果目标数据库已存在，您可能需要先创建一个新的空数据库，或添加 --clean 选项覆盖现有对象
- 根据备份的格式，使用适当的命令恢复
EOF

# 打包临时目录的内容
log_info "创建备份包: ${PACKAGE_PATH}..."
tar -czf "${PACKAGE_PATH}" -C "${TMP_DIR}" .
if [ $? -ne 0 ]; then
    log_error "打包失败"
    rm -rf "${TMP_DIR}"
    exit 1
fi

# 清理临时目录
log_info "清理临时目录..."
rm -rf "${TMP_DIR}"

log_success "备份包创建成功: ${PACKAGE_PATH}"
log_info "您可以将此包传输到目标服务器，按照包中的 README.txt 文件中的说明进行恢复"

# 显示执行时间
end_timer

log_info "打包脚本执行完成"
exit 0
